/*
 * Figure.h
 *
 *  Created on: 28/03/2013
 *      Author: gonzalo
 */

#ifndef FIGURE_H_
#define FIGURE_H_

#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <SOIL/SOIL.h>
#include <vector>

#define PI (3.141592653589793)

struct DatosVertice {
	glm::vec3 position;
	glm::vec3 normal;
	glm::vec3 tangent;
	glm::vec3 color;
	glm::vec2 texture;
};

class Figure {
protected:

	glm::mat4 * view_matrix;
	glm::vec3 position;

	GLfloat * vertex_buffer;
	GLuint * index_buffer;
	GLfloat * normal_buffer;
	GLfloat * tangent_buffer;
	GLfloat * texture_buffer;

	GLuint vertex_buffer_size;
	GLuint index_buffer_size;
	GLuint normal_buffer_size;
	GLuint tangent_buffer_size;
	GLuint texture_buffer_size;

	unsigned char* text_image_buffer;
	int text_image_witdh;
	int text_image_height;
	int text_image_channels;

	bool show_normals;

	// Proximamente
	DatosVertice * vertices;
	unsigned int * indices;
	GLuint size;
	GLuint vertex_buffer_object;
	GLuint index_buffer_object;
	GLuint vertex_size;
	GLuint index_size;
	GLuint type; // GL_QUADS, GL_TRIANGLES
	bool with_texture;
	GLuint texture;

	// Matriz que le da la forma al objeto
	glm::mat4 model_matrix;

	Figure(GLuint  program);
	virtual ~Figure();

	static void set_coords3(GLfloat * buffer,GLuint vertex_num,GLfloat x, GLfloat y, GLfloat z);
	static void set_coords2(GLfloat * buffer,GLuint vertex_num,GLfloat x, GLfloat y);
	void set_vertex_coords(GLuint vertex_num,GLfloat x, GLfloat y, GLfloat z);

public:

	virtual void draw(GLuint program, glm::mat4 & world_matrix) = 0;


	void traslate(glm::vec3 const & traslation);
	void rotate(GLfloat const & angle, glm::vec3 const & rotation_vector);
	void scale(glm::vec3 const & scale_factor);

	void set_model_matrix(glm::mat4 const & matrix);

	glm::vec3 get_position();

	glm::vec3 get_transformated_origin();

	glm::vec3 get_transformated_origin(glm::mat4 & matriz_vista);

	void draw_normals();

	void draw_normals(GLfloat * normals, GLuint * index, GLuint index_size);

	void set_show_normals(bool value);

	void calculate_and_bind_normal_matrix(GLuint  program,const glm::mat4 & matriz);

	void bind_model_matrix(GLuint  program,const glm::mat4 & matriz);

	void load_texture(const char* filename);

	void activate_texture(GLuint  program);

	void bind_tangent_buffer(GLuint  program,const char * buffer_name);

	void set_type(GLuint type);

	virtual void set_texture_id(GLuint id);

	virtual void change_texture_data(const std::vector<DatosVertice> & texturas);

};

#endif /* FIGURE_H_ */
